﻿using System.Collections;


namespace WenAntdUI.Controls;

/// <summary>
/// 支持添加任意类型对象的集合类，可作为控件属性使用
/// </summary>
public class ObjectCollection : CollectionBase
{
    /// <summary>
    /// 获取或设置指定索引处的元素
    /// </summary>
    /// <param name="index"></param>
    /// <returns></returns>
    public virtual object this[int index]
    {
        get { return List[index]; }
        set { List[index] = value; }
    }

    /// <summary>
    /// 将对象添加到集合的末尾
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public virtual int Add(object value)
    {
        return List.Add(value);
    }

    /// <summary>
    /// 将对象集合循环添加到集合的末尾
    /// </summary>
    /// <param name="values"></param>
    public virtual void AddRange(object[] values)
    {
        foreach (object value in values)
        {
            this.Add(value);
        }
    }

    /// <summary>
    /// 确定某元素是否在集合中
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public virtual bool Contains(object value)
    {
        return List.Contains(value);
    }

    /// <summary>
    /// 在集合的指定索引处插入一个元素
    /// </summary>
    /// <param name="index"></param>
    /// <param name="value"></param>
    public virtual void Insert(int index, object value)
    {
        List.Insert(index, value);
    }

    /// <summary>
    /// 从集合中移除特定对象的第一个匹配项
    /// </summary>
    /// <param name="value"></param>
    public virtual void Remove(object value)
    {
        List.Remove(value);
    }

    /// <summary>
    /// 返回集合中特定项的从零开始的索引
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public virtual int IndexOf(object value)
    {
        return List.IndexOf(value);
    }

    /// <summary>
    /// 将集合中的元素复制到一个数组中
    /// </summary>
    /// <param name="array"></param>
    /// <param name="index"></param>
    public virtual void CopyTo(Array array, int index)
    {
        InnerList.CopyTo(array, index);
    }

    /// <summary>
    /// 获取类型安全的元素
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="index"></param>
    /// <returns></returns>
    /// <exception cref="InvalidOperationException"></exception>
    public virtual T GetItem<T>(int index)
    {
        try
        {
            return (T)List[index];
        }
        catch (InvalidCastException)
        {
            throw new InvalidOperationException($"Item at index {index} is not of type {typeof(T).FullName}");
        }
    }

    /// <summary>
    /// 提供类型安全的迭代器
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public virtual new IEnumerator<T> GetEnumerator<T>()
    {
        foreach (object item in InnerList)
        {
            if (item is T typedItem)
                yield return typedItem;
        }
    }

    public virtual List<T> GetList<T>() { return [.. this.OfType<T>()]; }

    public virtual bool Any<T>(Func<T, bool> predicate) => GetList<T>().Any(predicate);

    public virtual T FirstOrDefault<T>(Func<T, bool> predicate)
    {
        return GetList<T>().FirstOrDefault(predicate);
    }
}